package org.Shiikong_Memory.SakuraBlockFrame.Builder;

import org.Shiikong_Memory.SakuraBlockFrame.Abnormal.NoInitAbnomal;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.Registry;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.Damageable;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.persistence.PersistentDataType;
import org.bukkit.plugin.Plugin;

import java.util.*;
import java.util.function.Consumer;

/**
 * 物品构建器
 * @author Shiikong_Memory
 * @version 1.0
 */
public class ItemBuilder {
    private static boolean isInit = false;
    private static Plugin plugin;
    private static NamespacedKey key;
    private static final Map<UUID, Consumer<PlayerInteractEvent>> CALLBACK_MAP = new HashMap<>();
    private Consumer<PlayerInteractEvent> interactHandler;
    private final ItemStack item;
    private final ItemMeta meta;
    private final Map<Class<? extends ItemMeta>, Consumer<ItemMeta>> metaProcessors = new HashMap<>();

    private ItemBuilder(Material material) {
        this.item = new ItemStack(material);
        this.meta = item.getItemMeta();
    }

    /**
     * 初始化
     * @param plugin 插件
     * @param NamespacedKeyName NamespacedKey名称
     */
    public static void init(Plugin plugin, String NamespacedKeyName) {
        ItemBuilder.plugin = plugin;
        plugin.getServer().getPluginManager().registerEvents(new ItemListener(), plugin);
        key = new NamespacedKey(plugin, NamespacedKeyName);
        isInit = true;
    }

    /**
     * 创建物品构建器
     * @param material 物品类型
     * @return 物品构建器
     */
    public static ItemBuilder create(Material material) {
        if (!isInit)throw new NoInitAbnomal("物品构建器");
        return new ItemBuilder(material);
    }

    /**
     * 创建物品构建器
     * @param material 物品类型
     * @return 物品构建器
     */
    public static ItemBuilder create(String material) {
        if (!isInit)throw new NoInitAbnomal("物品构建器");
        return new ItemBuilder(Registry.MATERIAL.match(material));
    }

    /**
     * 设置物品数量
     * @param amount 数量
     * @return 物品构建器
     */
    public ItemBuilder amount(int amount) {
        item.setAmount(Math.max(1, Math.min(64, amount)));
        return this;
    }

    /**
     * 设置物品名称
     * @param displayName 名称
     * @return 物品构建器
     */
    public ItemBuilder name(String displayName) {
        meta.setDisplayName(displayName);
        return this;
    }

    /**
     * 设置物品 Lore
     * @param lines Lore 行
     * @return 物品构建器
     */
    public ItemBuilder lore(String... lines) {
        List<String> lore = meta.hasLore() ? meta.getLore() : new ArrayList<>();
        lore.addAll(Arrays.asList(lines));
        meta.setLore(lore);
        return this;
    }

    /**
     * 应用元数据
     * @param metaType 元数据类型
     * @param applier 应用程序
     * @param <T> 元数据类型
     * @return 物品构建器
     */
    public <T extends ItemMeta> ItemBuilder applyMeta(Class<T> metaType, Consumer<T> applier) {
        if (metaType.isInstance(meta)) {
            applier.accept(metaType.cast(meta));
        } else {
            metaProcessors.put(metaType, (m) -> {
                if (metaType.isInstance(m)) {
                    applier.accept(metaType.cast(m));
                }
            });
        }
        return this;
    }

    /**
     * 设置物品耐久度
     * @param damage 耐久度
     * @return 物品构建器
     */
    public ItemBuilder durability(int damage) {
        return this.applyMeta(Damageable.class, d -> d.setDamage(damage));
    }

    /**
     * 设置物品附魔
     * @param enchantment 附魔
     * @param level 等级
     * @return 物品构建器
     */
    public ItemBuilder enchant(Enchantment enchantment, int level) {
        meta.addEnchant(enchantment, level, true);
        return this;
    }

    /**
     * 物品监听器
     */
    public ItemBuilder onInteract(Consumer<PlayerInteractEvent> handler) {
        this.interactHandler = handler;
        return this;
    }

    /**
     * 构建物品
     * @return 物品
     */
    public ItemStack build() {
        ItemMeta finalMeta = meta.clone();
        metaProcessors.forEach((clazz, consumer) -> consumer.accept(finalMeta));

        // 添加回调标识
        if (interactHandler != null && plugin != null) {
            UUID callbackId = UUID.randomUUID();
            PersistentDataContainer pdc = finalMeta.getPersistentDataContainer();
            pdc.set(new NamespacedKey(plugin, "item_callback"), PersistentDataType.STRING, callbackId.toString());
            CALLBACK_MAP.put(callbackId, interactHandler);
        }

        item.setItemMeta(finalMeta);
        return item.clone();
    }

    private static class ItemListener implements Listener {
        @EventHandler
        public void onPlayerInteract(PlayerInteractEvent event) {
            ItemStack item = event.getItem();
            if (item == null) return;

            ItemMeta meta = item.getItemMeta();
            if (meta == null) return;

            PersistentDataContainer pdc = meta.getPersistentDataContainer();

            if (pdc.has(key, PersistentDataType.STRING)) {
                String uuidStr = pdc.get(key, PersistentDataType.STRING);
                UUID itemId = UUID.fromString(uuidStr);
                Consumer<PlayerInteractEvent> handler = CALLBACK_MAP.get(itemId);
                if (handler != null) {
                    handler.accept(event);
                }
            }
        }
    }
}